package com.lsj.service.impl;

import cn.hutool.core.convert.Convert;
import com.lsj.dto.sys.AdminMenuTreeDto;
import com.lsj.mapper.SysAdminMenuMapper;
import com.lsj.mapper.entity.SysAdminMenu;
import com.lsj.service.AdminMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author:lin.sj
 * @Data:2021/7/19 22:11
 * @Desc:
 */
@Service
@Slf4j
public class AdminMenuServiceImpl implements AdminMenuService {
    @Autowired
    SysAdminMenuMapper sysAdminMenuMapper;

    /**
     * @Author: lin.sj
     * @Date: 2021/8/18 20:56
     * @Desc: 获取后台管理系统的菜单
     **/
    @Override
    public List<AdminMenuTreeDto> getMenuTree() {
        //获取所有菜单数据
        List<SysAdminMenu> totalMenus = sysAdminMenuMapper.selectList(null);
        totalMenus = totalMenus.stream().filter(m -> m.getId() != 0).collect(Collectors.toList());//去除根节点
        //计算菜单的层级
        Set<Integer> levelSet = totalMenus.stream().map(SysAdminMenu::getLevel).collect(Collectors.toSet());
        ArrayList<Integer> levels = new ArrayList<>(levelSet);
        //排序层级
        Collections.sort(levels);
        List<AdminMenuTreeDto> returnMenuTrees = new ArrayList<>();
        Map<Long, AdminMenuTreeDto> parentMap = new HashMap<>();
        int i = 1;
        for(Integer level:levels){
            List<AdminMenuTreeDto> menuTrees = totalMenus.stream()
                    //找出相同层级的数据
                    .filter(m -> m.getLevel().equals(level))
                    //转换数据类型
                    .map(m -> {
                        AdminMenuTreeDto menuTreeDto = Convert.convert(AdminMenuTreeDto.class, m);
                        return menuTreeDto;
                    }).collect(Collectors.toList());

            //遍历上一个循环中放入的map中的,检查本层次是否有对应的pid
            Set<Long> pids = parentMap.keySet();
            for(Long pid:pids){
                //过滤pid相同的数据
                List<AdminMenuTreeDto> children = menuTrees.stream().filter(m -> m.getMenuPid().equals(pid)).collect(Collectors.toList());
                //对本层级的数据进行排序
                children.sort((o1, o2) -> {
                    AdminMenuTreeDto m1 = (AdminMenuTreeDto)o1;
                    AdminMenuTreeDto m2 = (AdminMenuTreeDto)o2;
                    return m1.getSort() - m2.getSort();
                });
                AdminMenuTreeDto parentMenu = parentMap.get(pid);
                parentMenu.setChildren(children);
            }
            //清空上个循环放入的数据，放入本次循环的数据
            parentMap.clear();
            menuTrees.stream().forEach(m -> parentMap.put(m.getId(),m));
            if(i == 1){
                //将第一个层级的数据加入到返回的数据中
                returnMenuTrees.addAll(menuTrees);
                i++;
            }
        }
        return returnMenuTrees;
    }
}
